import express, { Request, Response, Router } from 'express';
import { PrismaClient, Prisma } from '@prisma/client';
import { authMiddleware } from '../middleware/auth';
import { ApiResponse } from '../utils/response';
import { priceService } from '../services/priceService';

const router: Router = express.Router();
const prisma = new PrismaClient();

// 提交充值申请
router.post('/apply', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { amount, bankInfo } = req.body;

    // 验证充值金额
    if (!amount || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0) {
      res.status(400).json(ApiResponse.error('충전 금액은 0보다 커야 합니다.'));
      return;
    }

    const depositAmount = parseFloat(amount);

    // 检查最小充值金额限制
    if (depositAmount < 10000) { // 最小充值1万韩元
      res.status(400).json(ApiResponse.error('최소 충전 금액은 10,000원입니다.'));
      return;
    }

    // 检查充值后总余额是否会超过数据库限制
    const userBalance = await prisma.userBalance.findUnique({
      where: { userId }
    });

    const currentTotal = userBalance ? parseFloat(userBalance.total.toString()) : 0;
    const afterDepositTotal = currentTotal + depositAmount;

    // 数据库字段限制: Decimal(15, 2) -> 最大值 9,999,999,999,999.99
    const MAX_BALANCE = 9999999999999.99;

    if (afterDepositTotal > MAX_BALANCE) {
      res.status(400).json(ApiResponse.error(
        `충전 후 총 잔액이 시스템 한도(₩${MAX_BALANCE.toLocaleString('ko-KR')})를 초과합니다. ` +
        `현재 잔액: ₩${currentTotal.toLocaleString('ko-KR')}, ` +
        `충전 가능한 최대 금액: ₩${(MAX_BALANCE - currentTotal).toLocaleString('ko-KR')}`
      ));
      return;
    }

    // 检查是否有待处理的充值申请
    const pendingDeposit = await prisma.depositRecord.findFirst({
      where: {
        userId,
        status: 'PENDING'
      }
    });

    if (pendingDeposit) {
      res.status(400).json(ApiResponse.error('처리되지 않은 충전 신청이 있습니다. 관리자 검토를 기다려 주세요.'));
      return;
    }

    // 获取实时NEAR价格并计算锁定数量
    const priceData = await priceService.getNearPriceData();
    const nearPrice = priceData.price;

    if (!nearPrice || nearPrice <= 0) {
      res.status(500).json(ApiResponse.error('NEAR 가격을 불러오지 못했습니다. 잠시 후 다시 시도해 주세요.'));
      return;
    }

    const rawNearAmount = depositAmount / nearPrice;
    const lockedNearAmount = parseFloat(rawNearAmount.toFixed(4));

    // 创建充值记录
    const deposit = await prisma.depositRecord.create({
      data: {
        userId,
        amount: new Prisma.Decimal(depositAmount),
        lockedNearAmount: new Prisma.Decimal(lockedNearAmount),
        lockedNearPrice: new Prisma.Decimal(nearPrice),
        bankInfo: bankInfo || '은행 송금',
        status: 'PENDING'
      }
    });

    res.json(ApiResponse.success({
      id: deposit.id,
      amount: Number(deposit.amount),
      status: deposit.status,
      createdAt: deposit.createdAt,
      lockedNearAmount: Number(deposit.lockedNearAmount),
      lockedNearPrice: Number(deposit.lockedNearPrice)
    }, '충전 신청이 접수되었습니다. 관리자 검토를 기다려 주세요.'));
  } catch (error) {
    console.error('충전 신청 오류:', error);
    res.status(500).json(ApiResponse.error('충전 신청에 실패했습니다. 잠시 후 다시 시도해 주세요.'));
  }
});

// 获取充值历史记录
router.get('/history', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { page = 1, limit = 20, status } = req.query;

    // 构建查询条件
    const where: any = { userId };
    if (status && status !== 'all') {
      where.status = status as string;
    }

    // 获取充值记录
    const deposits = await prisma.depositRecord.findMany({
      where,
      select: {
        id: true,
        amount: true,
        lockedNearAmount: true,
        lockedNearPrice: true,
        status: true,
        bankInfo: true,
        adminNote: true,
        createdAt: true,
        processedAt: true
      },
      orderBy: { createdAt: 'desc' },
      skip: (Number(page) - 1) * Number(limit),
      take: Number(limit)
    });

    // 获取总记录数
    const total = await prisma.depositRecord.count({
      where
    });

    // 统计各상태的数量
    const statusCounts = await prisma.depositRecord.groupBy({
      by: ['status'],
      where: { userId },
      _count: {
        status: true
      }
    });

    const summary = {
      pending: Number(statusCounts.find(s => s.status === 'PENDING')?._count.status) || 0,
      confirmed: Number(statusCounts.find(s => s.status === 'CONFIRMED')?._count.status) || 0,
      failed: Number(statusCounts.find(s => s.status === 'FAILED')?._count.status) || 0,
      cancelled: Number(statusCounts.find(s => s.status === 'CANCELLED')?._count.status) || 0
    };

    // 将 Decimal 类型转换为数字
    const formattedDeposits = deposits.map(deposit => ({
      ...deposit,
      amount: Number(deposit.amount),
      lockedNearAmount: Number(deposit.lockedNearAmount || 0),
      lockedNearPrice: Number(deposit.lockedNearPrice || 0)
    }));

    res.json(ApiResponse.success({
      records: formattedDeposits,
      summary,
      pagination: {
        page: Number(page),
        limit: Number(limit),
        total: Number(total),
        totalPages: Math.ceil(Number(total) / Number(limit))
      }
    }));
  } catch (error) {
    console.error('충전 내역 조회 오류:', error);
    res.status(500).json(ApiResponse.error('충전 내역 조회에 실패했습니다.'));
  }
});

// 获取充值详情
router.get('/:id', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { id } = req.params;

    const deposit = await prisma.depositRecord.findFirst({
      where: {
        id: parseInt(id),
        userId
      },
      select: {
        id: true,
        amount: true,
        lockedNearAmount: true,
        lockedNearPrice: true,
        status: true,
        bankInfo: true,
        receipt: true,
        adminNote: true,
        createdAt: true,
        processedAt: true,
        user: {
          select: {
            name: true,
            withdrawalBank: true,
            withdrawalAccount: true,
            accountHolder: true
          }
        }
      }
    });

    if (!deposit) {
      res.status(404).json(ApiResponse.error('충전 기록이 존재하지 않습니다.'));
      return;
    }

    const normalizedDeposit = {
      ...deposit,
      amount: Number(deposit.amount),
      lockedNearAmount: Number(deposit.lockedNearAmount || 0),
      lockedNearPrice: Number(deposit.lockedNearPrice || 0)
    };

    res.json(ApiResponse.success(normalizedDeposit));
  } catch (error) {
    console.error('충전 상세 조회 오류:', error);
    res.status(500).json(ApiResponse.error('충전 상세 조회에 실패했습니다.'));
  }
});

// 取消充值申请（仅限待处理상태）
router.post('/:id/cancel', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { id } = req.params;

    // 查找充值记录
    const deposit = await prisma.depositRecord.findFirst({
      where: {
        id: parseInt(id),
        userId,
        status: 'PENDING'
      }
    });

    if (!deposit) {
      res.status(404).json(ApiResponse.error('충전 기록이 없거나 취소할 수 없습니다.'));
      return;
    }

    // 更新상태为已取消
    const updatedDeposit = await prisma.depositRecord.update({
      where: { id: parseInt(id) },
      data: {
        status: 'CANCELLED',
        processedAt: new Date()
      }
    });

    res.json(ApiResponse.success(updatedDeposit, '충전 신청이 취소되었습니다.'));
  } catch (error) {
    console.error('충전 신청 취소 오류:', error);
    res.status(500).json(ApiResponse.error('충전 신청 취소에 실패했습니다.'));
  }
});

export default router;
